<?php
/**
 *  User class file
 */

/**
 * This is the model class for table "{{user}}".
 *
 * The followings are the available columns in table '{{user}}':
 * 
 * @uses MyModel
 * @package 
 * @property integer $id
 * @property string $username
 * @property string $password
 * @property string $salt
 * @property string $email
 * @property string $profile
 * @property string $lastName
 * @property string $firstName
 * @version $Rev: 7 $
 * @author Joachim Werner <joachim.werner@diggin-data.de> 
 */
class User extends MyModel
{
    /**
     * The followings are the available columns in table 'tbl_user':
     * @var integer $id
     * @var string $username
     * @var string $password
     * @var string $salt
     * @var string $email
     * @var string $profile
     * @var string $lastName
     * @var string $firstName
    */
    // {{{ *** Members ***
    /**
     * @var string
     */
    var $nameFields = "lastName;firstName";
    /**
     * @var string
     */
    var $nameFormat = "{1}, {2}";
    /**
     * Does this model use record revisions?
     * @var bool
     */
    var $usesRevision   = false;
    /**
     * proxy for db field "password", which will only be hashed and updated if this is non-empty
     * @var string
     */ 
    public $password2;

    Const NAMETYPE_FIRST1_LAST  = 1;
    Const NAMETYPE_FIRST_LAST   = 2;
    Const NAMETYPE_LAST_C_FIRST = 3;
    Const NAMETYPE_LAST_C_FIRST1 = 4;

    // }}} End Members
    // {{{ *** Methods ***
    // {{{ model
    /**
     * Returns the static model of the specified AR class.
     * @return CActiveRecord the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    } // }}}
    // {{{ tableName
    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return '{{User}}';
    } // }}}
    // {{{ rules
    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('username, email, lastName, firstName, birthDate', 'required'),
            array('username, password, email, lastName, firstName', 'length', 'max'=>128),
            array('salutation', 'length', 'max'=>10, 'on'=>'register'),
            array('registrationComplete','boolean'),
            array('password, password2','required','on' => 'insert,passwordChange,register'),
            array('birthDate','checkDateNotEmpty','on'=>'insert,register,update'),
            // array('birthDate', 'type', 'type' => 'date', 'message' => '{attribute}: is not a date!', 'dateFormat' => CLocale::getInstance(Yii::app()->language)->getDateFormat('medium')),
            array('password','comparePasswords','on'=>'insert,update,passwordChange'),
            array('username','userIdIsUnique','on'=>'insert'),
            array('profile,password2,registrationComplete', 'safe'), 
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, username, email, profile, lastName, firstName, birthDate', 'safe', 'on'=>'search'),
        );
    } // }}} 
    // {{{ relations
    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'posts'             => array(self::HAS_MANY,   'Post',           'author_id'),
            'authAssignments'   => array(self::HAS_MANY,   'AuthAssignment', 'userid'),
            //'settings'          => array(self::BELONGS_TO, 'CompanySetting', 'companyId'),
            'projects'          => array(self::MANY_MANY, 'Project','UserProject(userId, projectId)'),
        );
    } // }}} 
    // {{{ attributeLabels
    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id'            => Yii::t('site','ID'),
            'username'      => Yii::t('site','Username'),
            'password'      => Yii::t('site','Password'),
            'password2'     => Yii::t('site','Password (confirm)'),
            'newPassword1'  => Yii::t('site','Password'),
            'newPassword2'  => Yii::t('site','Password (confirm)'),
            'salt'          => Yii::t('site','Salt'),
            'email'         => Yii::t('site','Email'),
            'profile'       => Yii::t('site','Profile'),
            'salutation'    => Yii::t('site','Salutation'),
            'lastName'      => Yii::t('site','Lastname'),
            'firstName'     => Yii::t('site','Firstname'),
            'birthDate'     => Yii::t('site','Date of Birth'),
            'lastLoginTimestamp' => Yii::t('site','Last Login'),
        );
    } // }}} 
    // {{{ userIdIsUnique
    /**
     * Checks if the given user name is a new one
     */
    public function userIdIsUnique($attribute, $parameters)
    {
        $users = User::model()->findAllByAttributes(array('username'=>$this->username));
        if(count($users)>0)
            $this->addError('username',Yii::t('site',"The user name already exists."));
    } // }}} 
    // {{{ validatePassword
    /**
     * Checks if the given password is correct.
     * @param string the password to be validated
     * @return boolean whether the password is valid
     */
    public function validatePassword($password)
    {
        return $this->hashPassword($password,$this->salt)===$this->password;
    }
    // }}} 
    // {{{ comparePasswords
    public function comparePasswords($attribute,$params)
    {
        if($this->password=='' and !isset($this->password2)) return;
        if(trim($this->password)=='' and trim($this->password2)=='') {
            unset($this->password, $this->password2);
            return;
        }
        // Passwords dont't match
        if(trim($this->password)!='' and trim($this->password)!=trim($this->password2)) {
            $this->addError('password',Yii::t('site',"The passwords don't match"));
            //echo par($this);
        }
    } // }}}
    // {{{ beforeSave 
    public function beforeSave() {
        $this->username = strtolower($this->username);
        if (!empty($this->password)) {
            $this->salt = $this->generateSalt();
            $this->password = $this->hashPassword($this->password,$this->salt);
        }
        return parent::beforeSave();
    } // }}} 
    // {{{ hashPassword
    /**
     * Generates the password hash.
     * @param string password
     * @param string salt
     * @return string hash
     */
    public function hashPassword($password,$salt)
    {
        return md5($salt.$password);
    } // }}} 
    // {{{ generateSalt
    /**
     * Generates a salt that can be used to generate a password hash.
     * @return string the salt
     */
    protected function generateSalt()
    {
        return uniqid('',true);
    } // }}} 
    // {{{ search
    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id);
        $criteria->compare('username',$this->username,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('salt',$this->salt,true);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('profile',$this->profile,true);
        $criteria->compare('lastName',$this->profile,true);
        $criteria->compare('firstName',$this->profile,true);
        $criteria->compare('birthDate',$this->birthDate,true);
        $criteria->compare('registrationComplete',$this->registrationComplete,true);
        $criteria->order = 'lastname,firstName';

        return new CActiveDataProvider(get_class($this), array('criteria'=>$criteria,));
    } // }}} 
    // {{{ afterDelete
    /**
     * This is invoked after the record is deleted.
     */
    protected function afterDelete()
    {
        parent::afterDelete();
        AuthAssignment::model()->deleteAll('userid='.$this->id);
    } // }}} 
    // {{{ getFullName
    /**
     * Gets the user's name in various formatsgetName 
     * 
     * @param mixed $type 
     * @access public
     * @return void
     */
    public function getFullName($type=self::NAMETYPE_FIRST1_LAST)
    {
        switch($type)
        {
            case self::NAMETYPE_FIRST1_LAST:
                $result = sprintf(
                    "%s.%s",
                    substr($this->firstName,0,1),
                    $this->lastName
                );
                break;
            case self::NAMETYPE_LAST_C_FIRST:
                $result = sprintf(
                    "%s, %s",
                    $this->lastName,
                    $this->firstName
                );
                break;
            case self::NAMETYPE_LAST_C_FIRST1:
                $result = sprintf(
                    "%s, %s",
                    $this->lastName,
                    substr($this->firstName,0,1)
                );
                break;
            default:
                $result = $this->firstName.' '.$this->lastName;
                break;
        }
        return $result;
    } // }}} 
    // {{{ getSelectOptions
    public function getSelectOptions()
    {
        $criteria = new CDbCriteria;
        $criteria->order = 'lastName,firstName';
        $models = $this->findAll($criteria);
        $tmp = array();
        foreach($models as $model)
            $tmp[$model->id] = sprintf("%s, %s", $model->lastName, $model->firstName);
        return $tmp;
    } // }}} 
    // {{{ getFirst1Last
    /**
     * Gets the user's name like 'J.Werner' 
     * 
     * @access public
     * @return string
     */
    public function getFirst1Last()
    {
        return sprintf(
            "%s.%s",
            substr($this->firstName,0,1),
            $this->lastName
        );
    } // }}} 
    // {{{ getSalutationOptions
    public function getSalutationOptions()
    {
        return array(
            '' => '',
            'Mr.' => Yii::t('site','Mr.'),
            'Mrs.' => Yii::t('site','Mrs.')
        );
    } // }}} 
    // {{{ getFirstLastName
    /**
     * Gets the user's name like 'Joachim Werner' 
     * 
     * @access public
     * @return string
     */
    public function getFirstLastName()
    {
        return sprintf(
            "%s %s",
            $this->firstName,
            $this->lastName
        );
    } // }}} 
    // {{{ getLastFirstName
    /**
     * Gets the user's name like 'Werner, Joachim' 
     * 
     * @access public
     * @return string
     */
    public function getLastFirstName()
    {
        return sprintf(
            "%s, %s",
            $this->lastName,
            $this->firstName
        );
    } // }}} 
    // {{{ createDataDir
    /**
     * Creates a user's data (sub-) directory
     * 
     * @param string $subdir 
     * @access public
     * @return bool TRUE, if directory was created or exists. FALSE else
     */
    public function createDataDir($subdir=null)
    {
        $path = Yii::app()->basePath.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'users';
        // DEBUG echo "<li>path: $path";
        // Create all users base dir
        if(!is_dir($path))
            mkdir($path);
        // Create user's sub-dir
        $path .= DIRECTORY_SEPARATOR.$this->id;
        if(!is_dir($path))
            mkdir($path);
        // Create sub-dir
        if(is_null($subdir))
            return true;
        $path .= DIRECTORY_SEPARATOR.$subdir;
        if(!is_dir($path))
            mkdir($path);
        return is_dir($path);
    } // }}} 
    // {{{ getDataDir
    /**
     * Gets the path to a user's data (sub-) directory
     * 
     * @param string $subdir 
     * @access public
     * @return string The complete path
     */
    public function getDataDir($subdir=null)
    {
        $path = Yii::app()->basePath.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'users';
        $path .= DIRECTORY_SEPARATOR.$this->id;
        $path .= DIRECTORY_SEPARATOR.$subdir;
        if(!is_dir($path))
            return null;
        return $path;
    } // }}} 
    // {{{ getAuthAssignmentsToArray
    public function getAuthAssignmentsToArray()
    {
        $result = array();
        foreach($this->authAssignments as $authAssignment) {
            if(isset($this->companyAuthItems[$authAssignment->itemname]))
                $result[] = $this->companyAuthItems[$authAssignment->itemname];
            else
                $result[] = '('.$authAssignment->itemname.')';
        }
        return $result;
    } // }}} 
    public function isOwnerOfProject($projectId)
    {
        $sql = "SELECT COUNT(*) FROM UserProject WHERE userId=:userId AND projectId=:projectId";
        $result = Yii::app()->db->createCommand($sql)->queryScalar(array(':userId'=>$this->id,':projectId'=>$projectId));
        if($result>0)
            return true;
        else
            return false;
    }
    // }}} End Methods
}
/* vim:set ai sw=4 sts=4 et fdm=marker fdc=4: */
